package com.smsc.headend.task.engine.handler.impl.dcuparam;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.smsc.headend.common.enums.errorcode.TaskHandlerErrorCode;
import com.smsc.headend.common.utils.CosemUtils;
import com.smsc.headend.common.utils.CustomStringUtils;
import com.smsc.headend.module.data.enums.OperationGroup;
import com.smsc.headend.module.protocol.DeviceData;
import com.smsc.headend.module.protocol.cosem.bo.CosemData;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.module.template.dcu.entity.TemplateDcuAutoCollTask;
import com.smsc.headend.task.engine.dao.TaskDAO;
import com.smsc.headend.task.engine.exception.UDISTaskHandlerException;
import com.smsc.headend.task.engine.handler.TaskHandler;
import com.smsc.headend.task.engine.service.CosemXmlService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.smsc.headend.task.engine.utils.StepKeyUtil.getStepKey;


/**
 * @author wxh
 * @date 2020/12/15 20:23
 */
@Slf4j
public class ReadDcuCollSchemeHandler implements TaskHandler {
    @Autowired
    TaskDAO taskDAO;
    @Autowired
    CosemXmlService cosemXmlService;

    @Override
    public int handle(Task task, AtomicTask atomicTask, DeviceData deviceData, String actionResult) throws UDISTaskHandlerException {
        if (!(deviceData instanceof CosemData)) {
            throw new UDISTaskHandlerException(TaskHandlerErrorCode.DEVICE_DATA_TYPE_NOT_SUPPORT.toString());
        }

        CosemData cosemData = (CosemData) deviceData;

        List<TemplateDcuAutoCollTask> collTasks = new ArrayList<>();
        if(cosemData.getChild() != null) {
            for (int i = 0; i < cosemData.getChild().size(); i++) {
                TemplateDcuAutoCollTask collTask = new TemplateDcuAutoCollTask();
                CosemData structData = cosemData.getChild().get(i);

                CosemData uploadBaseTimeData = structData.getChild().get(0);
                Date date = new Date();
                // 这个dateTime wasion是dateTime格式 威士顿是octString格式
                if (StrUtil.equalsIgnoreCase("OctetString", uploadBaseTimeData.getType())) {
                    date = CosemUtils.parseOctStringDataTime((String) cosemXmlService.getData(uploadBaseTimeData.getType(), uploadBaseTimeData.getValue()));
                } else if (StrUtil.equalsIgnoreCase("DateTime", uploadBaseTimeData.getType())){
                    date = (Date) cosemXmlService.getData(uploadBaseTimeData.getType(), uploadBaseTimeData.getValue());
                }
                Long tvUploadBase = date.getTime() / 1000L;
                collTask.setTvUploadBase(tvUploadBase);

                CosemData uploadCircleUnitData = structData.getChild().get(1);
                Integer uploadCircleUnit = Convert.toInt(cosemXmlService.getData(uploadCircleUnitData.getType(), uploadCircleUnitData.getValue()));
                collTask.setUploadCircleUnit(uploadCircleUnit);

                CosemData uploadCircleData = structData.getChild().get(2);
                Long uploadCircle = Convert.toLong(cosemXmlService.getData(uploadCircleData.getType(), uploadCircleData.getValue()));
                collTask.setUploadCircle(uploadCircle);

                CosemData uploadTaskNoData = structData.getChild().get(3);
                Long uploadTaskNo = Convert.toLong(cosemXmlService.getData(uploadTaskNoData.getType(), uploadTaskNoData.getValue()));
                collTask.setTaskNo(uploadTaskNo);

                CosemData uploadTaskTypeData = structData.getChild().get(4);
                Long uploadTaskType = Convert.toLong(cosemXmlService.getData(uploadTaskTypeData.getType(), uploadTaskTypeData.getValue()));
                collTask.setTaskType(uploadTaskType);

                CosemData uploadTaskObisData = structData.getChild().get(5);
                List<String> obisList = new ArrayList<>();
                for (CosemData obisChildData : uploadTaskObisData.getChild()) {
                    String obis = (String) cosemXmlService.getData(obisChildData.getType(), obisChildData.getValue());
                    obisList.add(CustomStringUtils.parseHexObisCodeToInt(obis));
                }
                collTask.setObisList(obisList);

                CosemData uploadGatherTimeData = structData.getChild().get(6);
                // 这个dateTime wasion是dateTime格式 威士顿是octString格式
                Date dateGatherTime = new Date();
                if (StrUtil.equalsIgnoreCase("OctetString", uploadBaseTimeData.getType())) {
                    dateGatherTime = CosemUtils.parseOctStringDataTime((String) cosemXmlService.getData(uploadGatherTimeData.getType(), uploadGatherTimeData.getValue()));
                } else if (StrUtil.equalsIgnoreCase("DateTime", uploadBaseTimeData.getType())){
                    dateGatherTime = (Date) cosemXmlService.getData(uploadGatherTimeData.getType(), uploadGatherTimeData.getValue());
                }
                Long uploadGatherTime = dateGatherTime.getTime() / 1000L;
                collTask.setTvDataGather(uploadGatherTime);

                CosemData uploadCollTimeData = structData.getChild().get(7);
                Long uploadCollTime = Convert.toLong(cosemXmlService.getData(uploadCollTimeData.getType(), uploadCollTimeData.getValue()));
                collTask.setDcuCollectionTimeliness(uploadCollTime);

                collTasks.add(collTask);
            }
        }

        taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), "dcuCollSchemeList", collTasks, Long.valueOf(1 * 60 * 60), true);
        return 1;
    }

    @Override
    public int handleFailure(Task task, AtomicTask atomicTask, String message) {
        log.info("error {}, ", message);
        if (atomicTask.getGroupId() == OperationGroup.DcuGetCollScheme.getId().intValue()) {
            String stepOperationName = getStepKey(atomicTask, task);
            if (task.getIsODR()) {
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), stepOperationName, String.format("[%s]", message), 3600l, false);
            }
        }
        return -1;
    }
}
